package org.dromara.test;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.metadata.WriteSheet;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.web.domain.vo.DemoData;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 断言单元测试案例
 *
 * @author Lion Li
 */
@DisplayName("测试 merge测试案例")
public class AfMasterTest2 {

    @DisplayName("af_master获取方法")
    @Test
    public void getAfMaster2() throws IOException {
        // 今天的日期
        String today = DateUtil.today();
        // 昨天的日期
        String yesterday = DateUtil.format(DateUtil.offsetDay(DateUtil.parse(today), -1), "yyyy-MM-dd");
        // 前天的日期
        String beforeYesterday = DateUtil.format(DateUtil.offsetDay(DateUtil.parse(today), -2), "yyyy-MM-dd");

        // 从结束日期往前几天开始
        int fromDays = 3; // 0表示开始和结束是一天
        // 结束日期
        String to = yesterday;
        // 定义文件存储路径
        String filePath = "/Users/ztx/Downloads/csv/";
        // 定义文件名
        String targetName = "af_master_"+today+".csv";
        String yesterdayName = "af_master_"+yesterday+".csv";
        // 合并后的文件
        String mergeName = "af_master_all.csv";
        String todayMergeName = "af_master_all_"+today+".csv";
        String yesterdayMergeName = "af_master_all_"+yesterday+".csv";
        StringBuilder allBody = new StringBuilder();

        for (int i = 0; i <= fromDays; i++) {
            // 如果i=0，表示开始和结束是一天
            String from = DateUtil.format(DateUtil.offsetDay(DateUtil.parse(to), -i), "yyyy-MM-dd");
            String newTargetName = "af_master_"+from+".csv";
            System.out.println("生成: " + newTargetName);
            String fileBody = getAndSaveFile(from, from, filePath, newTargetName);
            // 如果是第一个直接拼接
            if (i == 0) {
                allBody.append(fileBody);
            } else {
                // 如果不是第一个,先去掉第一行，使用截取字符串的方法
                String newBody = fileBody.substring(fileBody.indexOf("\n") + 1);
                allBody.append(newBody);
            }
        }
        // 保存一段时间内合并后的文件
        String mergeNameWithDays = "af_master_"+to+"至"+DateUtil.format(DateUtil.offsetDay(DateUtil.parse(to), -fromDays), "yyyy-MM-dd") +"all.csv";
        FileUtil.writeUtf8String(allBody.toString(), filePath + mergeNameWithDays);
        //  合并所有的文件
        // 方案一
//        String everyDayMergeBody = readEveryDayFile(filePath);
//        if(StringUtils.isBlank(everyDayMergeBody)){
//            return;
//        }
//        FileUtil.writeUtf8String(everyDayMergeBody, filePath + mergeName);
        //方案二
        readAndWriteWithEasyExcel(filePath, mergeName);
    }

    public String getAndSaveFile(String from, String to, String filePath, String targetName) throws IOException {
        // 定义列名
        String groupings = "app_id,pid,af_prt,c,af_adset,af_ad,af_channel,af_siteid,af_keywords,is_primary,af_c_id,af_adset_id,af_ad_id,install_time,attributed_touch_type,geo";
        String kpis = "installs,retention_day_1";
        String url = "https://hq1.appsflyer.com/api/master-agg-data/v4/app/all";
        String headerValue = "Bearer eyJhbGciOiJBMjU2S1ciLCJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiSldUIiwiemlwIjoiREVGIn0.xLcr1iHi4K45wp4S42HhTuBZTy7oM1G3-aMlbLv46LnS6gv1_t_EFA.zGTZB8HkKsUp1-4t.1SFjlC0k3IzG07c_B34woeZ6KCbvWJxWTsC_rmBZVgTLUzflZ-PV2lTuH6Htl9eV3X_zW1g6udZQVS6DG1yihVSSPxCb0DwzmMHbad_i1wLvd4TX8GkjFN6yBYV0IB7vGMn8f5FJq9SSZbVnTBYlY5V0sexnlaxVcNDFEsDxUo4ewVAZktbHpPjNerWc6JO7N89Qtan_OdaZKbIYhB6F5hFK9At5HqL3_OGYwaOXCJVdJFHPbrorfIm8gMHDB3TcamdkmiUhA-NO1StFhO4DB4nNgZ_omYieDZpVSPVmvradPsg3mUiHuapvsX2RE4rxthwJuoGK__jmV5A1daq_asfE6c0U.nmNZonlns97TDWgRPYCm7g";
        String header = "Authorization";
        // 定义请求参数
        Map<String, Object> params = new HashMap<>();
        params.put("from", from);
        params.put("to", to);
        params.put("groupings", groupings);
        params.put("kpis", kpis);
        // 发送请求
        String body = HttpUtil.createGet(url)
            .header(header, headerValue)
            .form(params)
            .execute().body();
        //  body 是csv数据
        //存储
        FileWriter writer = new FileWriter(filePath + targetName);
        writer.write(body);
        writer.flush();
        writer.close();
        return body;
    }

    public String readEveryDayFile(String filePath) throws IOException {
        // 读取文件夹 里的文件，找出 .csv 文件 并且格式是 af_master_2021-07-01.csv
        File file = new File(filePath);
        File[] files = file.listFiles();
        if(files == null || files.length == 0){
            System.out.println("文件夹为空");
            return "";
        }
        StringBuilder mergeBody = new StringBuilder();
        List<String> newFileNames = new ArrayList<>();
        for (int i = 0; i < files.length; i++) {
            String name = files[i].getName();
            // 不包含 all 不包含 "至"    长度大于17 小于25
            if (name.endsWith(".csv") && name.startsWith("af_master_") && !name.contains("all") && name.length() > 17 && name.length() < 25 && !name.contains("至") ) {
                newFileNames.add(name);
            }
        }
        for (int i = 0; i < newFileNames.size(); i++) {
            String name = newFileNames.get(i);
            StringBuilder body = new StringBuilder();
            System.out.println("合并--读取："+name);
            FileReader fileReader = new FileReader(filePath + name);
            BufferedReader bufferedReader = new BufferedReader(fileReader);
            String line = null;
            while ((line = bufferedReader.readLine()) != null) {
                body.append(line).append("\n");
            }
            if(i == 0){
                mergeBody.append(body);
            }else{
                String newBody = body.substring(body.indexOf("\n") + 1);
                mergeBody.append(newBody);
            }
            bufferedReader.close();
            fileReader.close();
        }
        return mergeBody.toString();
    }

    /**
     * 读取并写入withEasyExcel
     */
    public void readAndWriteWithEasyExcel(String filePath,String mergeName) {
        // 读取文件夹 里的文件，找出 .csv 文件 并且格式是 af_master_2021-07-01.csv
        File file = new File(filePath);
        File[] files = file.listFiles();
        if(files == null || files.length == 0){
            System.out.println("文件夹为空停止合并");
        }
        List<String> newFileNames = new ArrayList<>();
        for (int i = 0; i < files.length; i++) {
            String name = files[i].getName();
            // 不包含 all 不包含 "至"    长度大于17 小于25
            if (name.endsWith(".csv") && name.startsWith("af_master_") && !name.contains("all") && name.length() > 17 && name.length() < 25 && !name.contains("至") ) {
                newFileNames.add(name);
            }
        }
        try (ExcelWriter excelWriter = EasyExcel.write(filePath+mergeName, DemoData.class).build()) {
            // 这里注意 如果同一个sheet只要创建一次
            WriteSheet writeSheet = EasyExcel.writerSheet("model").build();
            for (int i = 0; i < newFileNames.size(); i++) {
                String name = newFileNames.get(i);
                System.out.println("合并--读取："+name);
                String s = filePath + name;
                // 根据s 获取inputStream
                InputStream inputStream = FileUtil.getInputStream(s);
                List<DemoData> list = ListUtils.newArrayList(); // 用于存储所有的数据
                EasyExcel.read(inputStream, DemoData.class, new PageReadListener<DemoData>(dataList -> {
                    //处理文件内容
                    dataList.forEach(data -> {
                        list.add(data);
                    });
                })).sheet().doRead();
                excelWriter.write(list, writeSheet);
            }

        }catch (Exception e){
            e.printStackTrace();
        }

    }

}

